from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.exc import IntegrityError
from datetime import datetime
import pymysql
from math import radians, sin, cos, sqrt, atan2

# 初始化Flask应用
app = Flask(__name__)

# 配置MySQL数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost/tourism?charset=utf8mb4'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_size': 10,
    'pool_recycle': 1800,
    'pool_pre_ping': True
}

# 初始化数据库
db = SQLAlchemy(app)


# ------------------ 数据模型定义 -------------------
class TouristAttraction(db.Model):
    __tablename__ = 'tourist_attractions'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, default='暂无描述')
    location = db.Column(db.String(50), nullable=False)
    image_url = db.Column(db.String(200))
    ticket_price = db.Column(db.Float)
    latitude = db.Column(db.Float)
    longitude = db.Column(db.Float)
    address = db.Column(db.String(200))
    rating = db.Column(db.Float, default=0.0)
    opening_hours = db.Column(db.String(100))
    contact_number = db.Column(db.String(20))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    reviews = db.relationship('TouristReview', backref='attraction', lazy=True)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'image_url': self.image_url,
            'ticket_price': self.ticket_price,
            'address': self.address,
            'rating': self.rating,
            'coordinates': {
                'latitude': self.latitude,
                'longitude': self.longitude
            },
            'opening_hours': self.opening_hours,
            'contact_number': self.contact_number
        }

    def to_detail_dict(self):
        data = self.to_dict()
        data['reviews'] = [review.to_dict() for review in self.reviews]
        return data


class TouristReview(db.Model):
    __tablename__ = 'tourist_reviews'

    id = db.Column(db.Integer, primary_key=True)
    attraction_id = db.Column(db.Integer, db.ForeignKey('tourist_attractions.id'))
    user_id = db.Column(db.Integer, nullable=False)
    username = db.Column(db.String(50))
    avatar = db.Column(db.String(200))
    comment = db.Column(db.Text, nullable=False)
    rating = db.Column(db.Float, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def to_dict(self):
        return {
            'id': self.id,
            'user_id': self.user_id,
            'username': self.username,
            'avatar': self.avatar,
            'comment': self.comment,
            'rating': self.rating,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }


# ------------------ 工具函数 -------------------
def calculate_distance(lat1, lng1, lat2, lng2):
    """计算两个坐标之间的距离（米）"""
    lat1, lng1, lat2, lng2 = map(radians, [lat1, lng1, lat2, lng2])
    dlat = lat2 - lat1
    dlng = lng2 - lng1
    a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlng / 2) ** 2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return 6371000 * c  # 地球半径6371km


# ------------------ API路由 -------------------
@app.route('/api/getNearbyAttractions', methods=['GET'])
def get_nearby_attractions():
    """获取附近景点接口（严格匹配前端需求）"""
    try:
        lng = float(request.args.get('lng'))
        lat = float(request.args.get('lat'))
    except (TypeError, ValueError):
        return jsonify({'error': 'Invalid longitude or latitude'}), 400

    # 获取所有景点并计算距离
    attractions = TouristAttraction.query.all()
    results = []

    for attr in attractions:
        distance = calculate_distance(lat, lng, attr.latitude, attr.longitude)
        if distance <= 10000:  # 10公里范围内
            attr_data = attr.to_dict()
            attr_data['distance'] = round(distance)
            results.append(attr_data)

    # 按距离排序
    results.sort(key=lambda x: x['distance'])

    return jsonify({'data': results[:20]})  # 最多返回20个


@app.route('/api/getAttractionDetail/<int:id>', methods=['GET'])
def get_attraction_detail(id):
    """获取景点详情接口（严格匹配前端需求）"""
    attraction = TouristAttraction.query.get(id)
    if not attraction:
        return jsonify({'error': 'Attraction not found'}), 404

    return jsonify({'data': attraction.to_detail_dict()})


# ------------------ 健康检查路由 -------------------
@app.route('/health', methods=['GET'])
def health_check():
    return jsonify({'status': 'healthy'})


# ------------------ 数据库初始化 -------------------
def init_db():
    with app.app_context():
        db.create_all()
        # 添加测试数据
        if not TouristAttraction.query.first():
            test_attraction = TouristAttraction(
                name='测试景点',
                description='这是一个测试景点',
                location='116.404,39.915',
                latitude=39.915,
                longitude=116.404,
                address='北京市测试地址',
                ticket_price=100.0,
                opening_hours='08:00-18:00',
                contact_number='13800138000'
            )
            db.session.add(test_attraction)
            db.session.commit()


# ------------------ 启动应用 -------------------
if __name__ == '__main__':
    init_db()
    app.run(host='0.0.0.0', port=5000, debug=True)